﻿using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal struct DXFBdr
    {
        private BorderStyle _dgBottom;
        private BorderStyle _dgDiag;
        private BorderStyle _dgLeft;
        private BorderStyle _dgRight;
        private BorderStyle _dgTop;
        private IcvXF _icvBottom;
        private IcvXF _icvDiag;
        private IcvXF _icvLeft;
        private IcvXF _icvRight;
        private IcvXF _icvTop;
        private bool _bitDiagDown;
        private bool _bitDiagUp;

        public uint Line3
        {
            get { return (uint) ((byte) IcvTop | ((byte) IcvBottom) << 7 | (byte) IcvDiag << 14 | (byte) DgDiag << 21); }
        }

        public ushort UShort7
        {
            get { var result =  (ushort) ((byte) IcvLeft | (byte) IcvRight << 7 );
            if (BitDiagDown)
                result |= 0x4000;
            if (BitDiagUp)
                result |= 0x8000;
                return result;
            }
        }

        public byte Byte6
        {
            get { return (byte) ((byte) DgTop | (byte) DgBottom << 4); }
        }

        public byte Byte5
        {
            get { return (byte) ((byte) DgLeft | (byte) DgRight << 4); }
        }

        public BorderStyle DgBottom
        {
            get { return _dgBottom; }
        }

        public BorderStyle DgDiag
        {
            get { return _dgDiag; }
        }

        public BorderStyle DgLeft
        {
            get { return _dgLeft; }
        }

        public BorderStyle DgRight
        {
            get { return _dgRight; }
        }

        public BorderStyle DgTop
        {
            get { return _dgTop; }
        }

        public IcvXF IcvBottom
        {
            get { return _icvBottom; }
        }

        public IcvXF IcvDiag
        {
            get { return _icvDiag; }
        }

        public IcvXF IcvLeft
        {
            get { return _icvLeft; }
        }

        public IcvXF IcvRight
        {
            get { return _icvRight; }
        }

        public IcvXF IcvTop
        {
            get { return _icvTop; }
        }

        public bool BitDiagDown
        {
            get { return _bitDiagDown; }
        }

        public bool BitDiagUp
        {
            get { return _bitDiagUp; }
        }

        public void Read(BinaryReader reader)
        {
            byte byte5 = reader.ReadByte();
            _dgLeft = (BorderStyle) (byte5 & 0xF);
            _dgRight = (BorderStyle) (byte5 >> 4);
            Contract.Assert((Byte5 == byte5));

            byte byte6 = reader.ReadByte();
            _dgTop = (BorderStyle) (byte6 & 0xF);
            _dgBottom = (BorderStyle) (byte6 >> 4);
            Contract.Assert((Byte6 == byte6));
            ushort ushort7 = reader.ReadUInt16();
            _icvLeft = (byte) (ushort7 & 0x7F);
            _icvRight = (byte) ((ushort7 >> 7) & 0x7F);
            this._bitDiagDown = (ushort7 & 0x4000) != 0;
            this._bitDiagUp = (ushort7 & 0x8000) != 0;
            Contract.Assert(UShort7 == ushort7);
            uint line3 = reader.ReadUInt32();
            _icvTop = (byte) (line3 & 0x7F);
            _icvBottom = (byte) ((line3 >> 7) & 0x7F);
            _icvDiag = (byte) ((line3 >> 14) & 0x7F);
            _dgDiag = (BorderStyle) ((line3 >> 21) & 0xF);
            Contract.Assert(Line3 == line3);
        }


        public void Write(BinaryWriter writer)
        {
            writer.Write(Byte5);
            writer.Write(Byte6);
            writer.Write(UShort7);
            writer.Write(Line3);
        }
    }
}